package com.example.ploy4j.service.impl;

import com.example.ploy4j.dto.ServerConfigDto;
import com.example.ploy4j.dto.mapper.ServerConfigMapper;
import com.example.ploy4j.entity.ServerConfig;
import com.example.ploy4j.repository.ServerConfigRepository;
import com.example.ploy4j.service.ServerConfigService;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class ServerConfigServiceImpl implements ServerConfigService {

    private static final Logger logger = LoggerFactory.getLogger(ServerConfigServiceImpl.class);
    private final ServerConfigRepository serverConfigRepository;
    private final ServerConfigMapper serverConfigMapper;

    @Override
    @Transactional
    public ServerConfigDto createServerConfig(ServerConfigDto serverConfigDto) {
        ServerConfig serverConfig = serverConfigMapper.toEntity(serverConfigDto);
        ServerConfig savedConfig = serverConfigRepository.save(serverConfig);
        return serverConfigMapper.toDto(savedConfig);
    }

    @Override
    @Transactional(readOnly = true)
    public Optional<ServerConfigDto> getServerConfigById(Long id) {
        return serverConfigRepository.findById(id)
                .map(serverConfigMapper::toDto);
    }

    @Override
    @Transactional(readOnly = true)
    public Optional<ServerConfigDto> getServerConfigByName(String name) {
        return serverConfigRepository.findByName(name)
                .map(serverConfigMapper::toDto);
    }

    @Override
    @Transactional(readOnly = true)
    public List<ServerConfigDto> getAllServerConfigs() {
        return serverConfigMapper.toDtoList(serverConfigRepository.findAll());
    }

    @Override
    @Transactional
    public ServerConfigDto updateServerConfig(Long id, ServerConfigDto serverConfigDto) {
        ServerConfig existingConfig = serverConfigRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("未找到ID为: " + id + " 的服务器配置"));
        serverConfigMapper.updateEntityFromDto(serverConfigDto, existingConfig);
        ServerConfig updatedConfig = serverConfigRepository.save(existingConfig);
        return serverConfigMapper.toDto(updatedConfig);
    }

    @Override
    @Transactional
    public void deleteServerConfig(Long id) {
        if (!serverConfigRepository.existsById(id)) {
            throw new EntityNotFoundException("未找到ID为: " + id + " 的服务器配置，无法删除");
        }
        serverConfigRepository.deleteById(id);
    }

    private Map<String, Object> performJschConnectionTest(String host, Integer port, String username, String password) {
        Map<String, Object> response = new HashMap<>();
        JSch jsch = new JSch();
        Session session = null;
        try {
            session = jsch.getSession(username, host, port);
            session.setPassword(password);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            config.put("PreferredAuthentications", "password");
            session.setConfig(config);
            session.setTimeout(15000);
            session.connect();

            response.put("success", true);
            response.put("message", "成功连接到 " + host + ":" + port);
        } catch (JSchException e) {
            logger.warn("JSch connection test failed for {}@{}:{}. Error: {}", username, host, port, e.getMessage());
            response.put("success", false);
            response.put("message", "连接测试失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("Unexpected error during JSch connection test for {}@{}:{}: {}", username, host, port, e.getMessage(), e);
            response.put("success", false);
            response.put("message", "连接测试时发生意外错误: " + e.getMessage());
        } finally {
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
        return response;
    }

    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> testConnection(Long id) {
        ServerConfig serverConfig = serverConfigRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("未找到ID为: " + id + " 的服务器配置，无法测试连接"));
        return performJschConnectionTest(serverConfig.getHost(), serverConfig.getPort(), serverConfig.getUsername(), serverConfig.getPassword());
    }

    @Override
    public Map<String, Object> testUnsavedConnection(ServerConfigDto tempServerConfigDto) {
        if (tempServerConfigDto == null) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "连接参数不完整，无法测试。");
            return response;
        }
        if (tempServerConfigDto.getHost() == null || tempServerConfigDto.getHost().isEmpty() ||
            tempServerConfigDto.getPort() == null ||
            tempServerConfigDto.getUsername() == null || tempServerConfigDto.getUsername().isEmpty() ||
            tempServerConfigDto.getPassword() == null || tempServerConfigDto.getPassword().isEmpty()) {
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "主机、端口、用户名和密码均为必填项才能测试连接。");
            return response;
        }
        return performJschConnectionTest(tempServerConfigDto.getHost(), tempServerConfigDto.getPort(), tempServerConfigDto.getUsername(), tempServerConfigDto.getPassword());
    }
} 